//////////////////////////////////////////////////////////////////////////
#pragma once


//////////////////////////////////////////////////////////////////////////
#include "Application.hpp"
#include "WindowManager.hpp"


namespace Application
{
	class WindowedApp
	{
	public:
		//
		WindowedApp( const char* argv, const std::string& companyName, const std::string& gameName );
		virtual ~WindowedApp();

		//
		virtual bool					Initialize()=0;
		virtual bool					Shutdown()=0;
		bool							Update();

		int								Run();

		Core::Script&					Script()			{return mScript;}
		Application::WindowManager&		WindowManager()		{return mWindowManager;}

		//
		typedef std::function< void () >	Update_t;
		bool							RegisterUpdate( const std::string& name, int32_t pri, Update_t );
		bool							UnregisterUpdate( const std::string& name, int32_t pri );

		//
		static WindowedApp*				Instance()			{return mpInstance;}

		//
		Application::Clock&				Clock()				{return mClock;}

	protected:
		bool							_RunGameScript();
		void							_RunRegisteredUpdates();
		void							_RemoveUpdates();
		bool							_LuaRegisterUpdate( const std::string& name, int32_t pri, luabridge::LuaRef refItem );

	private:
		//
		bool							_InitScript();

		//
		typedef std::unordered_map< std::string, Update_t >		UpdateGroup_t;
		typedef std::multimap< int32_t, UpdateGroup_t >			UpdateMap_t;

		typedef std::pair< std::string, int32_t >				RemovedUpdate_t;
		typedef std::vector< RemovedUpdate_t >					RemovedUpdateVector_t;

		//
		std::string						mCompanyName;
		std::string						mGameName;
		FileSystem::Initializer			mFileSystem;
		Core::Script					mScript;
		Application::WindowManager		mWindowManager;
		UpdateMap_t						mUpdateMap;
		RemovedUpdateVector_t			mUpdateRemovals;
		Application::Clock				mClock;

		static WindowedApp*				mpInstance;
	};
}
